#ifndef WL_EXT_NETWORK_H
#define WL_EXT_NETWORK_H

typedef void* wl_ext_tcp_handle;
typedef void* wl_ext_udp_handle;

enum {
    WL_EXT_NETWORK_SUCCESS = 0,
    WL_EXT_NETWORK_ERROR
};

/**
 * network callback
 * 
 * @param handle tcp handle 
 * @param tcp_event network event
 * @param context user context
 */
typedef void (*wl_ext_tcp_callback)(wl_ext_tcp_handle handle, int tcp_event, void* context);

/**
 * get host by name
 * 
 * @param resultCode result code
 * @param ip ip
 * @param context user context
 *  
 */
typedef void (*wl_ext_get_host_callback)(int resultCode,const char* ip, void* context);

// network event
enum {
    WL_EXT_TCP_CONNECTING = 0, // tcp connecting
    WL_EXT_TCP_CONNECTED,      // tcp connected
    WL_EXT_TCP_DISCONNECT,     // tcp disconnected
    WL_EXT_TCP_CAN_SEND,       // sending available
    WL_EXT_TCP_CAN_RECV,       // receiving available
    WL_EXT_TCP_ERROR           // tcp error
};


/**
 * 初始化平台的网络
 * 
 * @return 0 success, < 0 fail
 */
int wl_ext_network_init(void);

/**
 * deinit network
 */
void wl_ext_network_deinit(void);

/**
 * 创建一个TCP的连接，这是异步的，会立刻返回一个tcp的句柄，同时会立即进行连接
 * 所有的连接结果，会通过回调函数返回。因为一个tcp连接对应一个句柄，所以可以多个tcp连接同时进行
 * 每个tcp连接对应一个句柄，互不影响
 * 
 * @param ip server ip
 * @param port server port
 * @param callback callback
 * @param context user context
 * 
 * @return tcp handle, non-null if success, null if fail
 */
wl_ext_tcp_handle wl_ext_tcp_connect(const char* ip, int port, wl_ext_tcp_callback callback, void* context);

/**
 * 断开对应句柄的TCP连接
 * 
 * @param handle tcp handle
 */
void wl_ext_tcp_disconnect(wl_ext_tcp_handle handle);

/**
 * send data, in blocked way
 * 
 * @param handle tcp handle
 * @param data data
 * @param len data length
 * 
 * @return > 0, means bytes actually read, < 0 means error, 0 means should waiting
 *         当发送返回0，是等待回调通知可以继续发送的信息。
 */
int wl_ext_tcp_send(wl_ext_tcp_handle handle, const char* data, int len);

/**
 * read data, in blocked way
 * 
 * @param handle tcp handle
 * @param buffer buffer
 * @param len buffer length
 * 
 * @return > 0, means bytes actually read, < 0 means error, 0 means should waiting
 *         当接收返回0，是等待回调通知可以继续接收的信息。
 */
int wl_ext_tcp_recv(wl_ext_tcp_handle handle, char* buffer, int len);


/**
 * 创建一个绑定在本地端口的UDP
 * 
 * @param bindPort local port
 * 
 * @return udp handle, non-null if success, null if fail
 */
wl_ext_udp_handle wl_ext_udp_create(int bindPort);

/**
 * deinit udp
 *  
 * @param handle udp handle
 * @param ip server ip
 * @param port server port
 * @param data data
 * @param len data length
 * 
 * @return > 0, means bytes actually read, < 0 means error
 */
int wl_ext_udp_sendto(wl_ext_udp_handle handle, const char* ip, int port, const char* data, int len);

/**
 * read data, in blocked way
 * 
 * @param handle udp handle
 * @param buffer buffer
 * @param len buffer length
 * 
 * @return > 0, means bytes actually read, < 0 means error
 */
int wl_ext_udp_recvFrom(wl_ext_udp_handle handle, char* buffer, int len);

/**
 * 异步获取主机名，所有结果通过回调返回
 * 
 * @param name host name
 * @param callback callback
 * @param context user context
 * 
 * @return 0 success, < 0 fail
 *  
 */
int wl_ext_get_host_by_name_async(const char* name, wl_ext_get_host_callback callback, void* context);

/**
 * 同步获取主机名
 * 
 * @param name host name
 * @param ip ip
 * 
 * @return 0 success, < 0 fail
 *  
 */
int wl_ext_get_host_by_name_sync(const char* name, char* ip);

/**
 * 判断当前网络是否有效。
 * 
 * @return 1 valid, 0 invalid
 *  
 */
int wl_ext_is_network_valid(void);
#endif
